package com.betterjr.modules.accountSupervision.utils;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 
 * XML工具类
 * 
 * @author 齐卫刚
 * @version 1.0 2015-03-18
 * 	
 */
@SuppressWarnings("all")
public class ScfXmlUtil {

    private Document document;

    public ScfXmlUtil(final String xmlInfo) {
        try {
            // xmlInfo = xmlInfo.replaceAll("[\r\n,\r,\n]", "");
            document = DocumentHelper.parseText(xmlInfo);
        }
        catch (final Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 读取XML文件
     * @param fileName 文件名称
     * @return
     */
    public static Document loadFile(final String fileName) {
        try {
            final SAXReader saxReader = new SAXReader();
            return saxReader.read(ScfXmlUtil.class.getResource(fileName));
        }
        catch (final Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 得到指定的节点
     * @param document 报文
     * @param xpath 路径
     * @return
     */
    public static List<Node> getNodeList(final Document document, final String xpath) {
        return document.selectNodes(xpath);
    }

    /**
     * 得到指定节点列表
     * @param path 节点路径
     * @return 节点列表
     */
    public List getNodeList(final String path) {
        if (document != null && path != null && !"".equals(path)) {
            return document.selectNodes(path);
        }
        return null;
    }

    /**
     * 得到指定节点
     * @param nodeList 节点列表
     * @param index 指定位置
     * @return
     */
    public Node getNode(final List nodeList, final int index) {
        return (Node) nodeList.get(index);
    }

    /**
     * 得到节点信息
     * @param nodeList 节点列表
     * @param nodeName 节点名称
     * @return 节点信息
     */
    public String getText(final Node nodeParent, final String nodeName) {
        if (nodeParent != null) {
            final Node node = nodeParent.selectSingleNode(nodeName);
            if (node != null) {
                return node.getText();
            }
        }
        return "";
    }

    /** 
     * 格式化XML文档 
     * 
     * @param document xml文档 
     * @return 格式化后XML字符串 
     */
    public static String formatXML(final Document document) {
        final OutputFormat format = OutputFormat.createPrettyPrint();
        format.setExpandEmptyElements(true);
        final StringWriter sw = new StringWriter();
        final XMLWriter xw = new XMLWriter(sw, format);
        try {
            xw.write(document);
            xw.flush();
            xw.close();
        }
        catch (final IOException e) {
            System.out.println("格式化XML文档发生异常，请检查！" + e.getMessage());
        }
        return sw.toString();
    }

    /**
     * 得到节点内容
     * 
     * @param nodeList 节点列表
     * @param index 指定节点
     * @param nodeName 节点名称
     * @return 节点内容
     */
    public String getText(final List nodeList, final int index, final String nodeName) {
        final Node nodeParent = (Node) nodeList.get(index);
        return getText(nodeParent, nodeName);
    }

    /**
     * 得到报文主键
     * 
     * @param message 消息报文
     * @return
     */
    public static String getSerialID(final String message) {
        return splitValue(message, "<serialId>", "</serialId>");
    }

    /**
     * 得到机构代码
     * 
     * @param message 消息报文
     * @return
     */
    public static String getCorpCode(final String message) {
        return splitValue(message, "<corpCode>", "</corpCode>");
    }

    /**
     * 得到银行接口
     * 
     * @param message 消息报文
     * @return
     */
    public static String getCanalCode(final String message) {
        return splitValue(message, "<canalCode>", "</canalCode>");
    }

    /**
     * 得到交易名称
     * 
     * @param message 消息报文
     * @return
     */
    public static String getTradeName(final String message) {
        return splitValue(message, "<tradeName>", "</tradeName>");
    }

    public static String getElNameText(final String message, final String elName) {
        return splitValue(message, "<" + elName + ">", "</" + elName + ">");
    }

    /**
     * 得到单据编号
     * 
     * @param message 消息报文
     * @return
     */
    public static String getBillCode(final String message) {
        return splitValue(message, "<billCode>", "</billCode>");
    }

    /**
     * 得到消息类型
     * 
     * @param message 消息报文
     * @return
     */
    public static String getMsgType(final String message) {
        return splitValue(message, "<msgType>", "</msgType>");
    }

    /**
     * 得到指定节点内容
     * @param message 报文
     * @param start 开始节点
     * @param end 结束节点
     * @return 节点内容
     */
    public static String splitValue(final String message, final String start, final String end) {
        final int startIndex = message.indexOf(start);
        final int endIndex = message.indexOf(end);
        if (startIndex > -1 && endIndex > -1) {
            return message.substring(startIndex + start.length(), endIndex);
        }
        return null;
    }

    /**
     * 去除指定节点内容
     * @param message 报文
     * @param start 开始节点
     * @param end 结束节点
     * @return 结果报文
     */
    public static String removeValue(final String message, final String start, final String end) {
        final int startIndex = message.indexOf(start);
        final int endIndex = message.indexOf(end);
        if (startIndex > -1 && endIndex > -1) {
            String first = message.substring(0, startIndex);
            if (first != null) first = first.trim();
            String second = message.substring(endIndex + end.length());
            if (second != null) second = second.trim();
            return first + second;
        }
        return message;
    }

    /**
     * 转换明细信息字符串到明细列表
     * @param message 明细信息
     * @return
     */
    public static List<Map<String, String>> getDetailList(final String message) {
        final List<Map<String, String>> detailList = new ArrayList<Map<String, String>>();
        if (message != null && message.length() > 0) {
            // 格式：<map><key1>value1</key1><key2>value2</key2></map><map><key1>value1</key1><key2>value2</key2></map>
            final Document document = parseXML(
                    "<?xml version=\"1.0\" encoding=\"UTF-8\"?><loopData><map>" + message + "</map></loopData>");
            if (document != null) {
                final Element rootElement = document.getRootElement();
                if (rootElement != null) {
                    final List<Element> dataElementList = rootElement.elements("map");
                    if (dataElementList != null) {
                        for (final Element dataElement : dataElementList) {
                            final List<Element> elementList = dataElement.elements();
                            if (elementList != null) {
                                final Map<String, String> detailMap = new HashMap<String, String>();
                                for (final Element element : elementList) {
                                    final String name = element.getName();
                                    final String value = element.getTextTrim();
                                    detailMap.put(name, value);
                                }
                                detailList.add(detailMap);
                            }
                        }
                    }
                }
            }
        }
        return detailList;
    }
    /**
     * 转换明细信息字符串到明细列表
     * @param message 明细信息
     * @return
     */
    public static List<Map<String, String>> getDetailList1(final String message) {
        final List<Map<String, String>> detailList = new ArrayList<Map<String, String>>();
        if (message != null && message.length() > 0) {
            // 格式：<map><key1>value1</key1><key2>value2</key2></map><map><key1>value1</key1><key2>value2</key2></map>
            final Document document = parseXML(
                    "<?xml version=\"1.0\" encoding=\"UTF-8\"?><loopData>" + message + "</loopData>");
            if (document != null) {
                final Element rootElement = document.getRootElement();
                if (rootElement != null) {
                    final List<Element> dataElementList = rootElement.elements("list");
                    if (dataElementList != null) {
                        for (final Element dataElement : dataElementList) {
                            final List<Element> elementList = dataElement.elements();
                            if (elementList != null) {
                                final Map<String, String> detailMap = new HashMap<String, String>();
                                for (final Element element : elementList) {
                                    final String name = element.getName();
                                    final String value = element.getTextTrim();
                                    detailMap.put(name, value);
                                }
                                detailList.add(detailMap);
                            }
                        }
                    }
                }
            }
        }
        return detailList;
    }

    /**
     * 解析报文
     * @param message 消息报文
     * @return
     */
    public static Document parseXML(final String message) {
        try {
            return DocumentHelper.parseText(message);
        }
        catch (final Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
